package com;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.ServerSocketChannel;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;

public class LoggingDaytimeServer {

    private final static int PORT = 1113;
    private final static Logger auditLogger = Logger.getLogger("requests");
    private final static Logger errorLogger = Logger.getLogger("errors");
    private final static int THREAD_NUM = 50;

    public static void main(String[] args) {

        ExecutorService tp = Executors.newFixedThreadPool(THREAD_NUM);

        try (ServerSocket serverSocket = new ServerSocket(PORT)){

            while (true){

                try {
                    Socket conn = serverSocket.accept();

                    tp.submit(new PooledThread(conn));
                }catch (RuntimeException ex){

                    errorLogger.log(Level.SEVERE,"unexpected error " + ex.getMessage(),ex);

                }

            }

        } catch (IOException e) {
            errorLogger.log(Level.SEVERE,"couldn't start server",e);
        }catch (RuntimeException ex){
            errorLogger.log(Level.SEVERE,"couldn't start server:"+ex.getMessage(),ex);
        }

    }

    public static class PooledThread implements Callable<Void>{

        private Socket conn;

        public PooledThread(Socket conn) {
            this.conn = conn;
        }

        @Override
        public Void call(){
            try {
                Date now = new Date();
                //记录日志
                auditLogger.info(now + " " + conn.getRemoteSocketAddress());
                Writer writer = new OutputStreamWriter(conn.getOutputStream());
                writer.write(now.toString()+"\r\n");
                writer.flush();

            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    conn.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            return null;

        }
    }

}
